package hk.xing.boot.saToken.config;

import cn.dev33.satoken.error.SaErrorCode;
import cn.dev33.satoken.exception.NotLoginException;
import cn.dev33.satoken.fun.SaParamFunction;
import cn.dev33.satoken.interceptor.SaInterceptor;
import cn.dev33.satoken.strategy.SaAnnotationStrategy;
import cn.hutool.json.JSONUtil;
import hk.xing.boot.enums.APIResponseEnum;
import hk.xing.boot.pojo.ApiResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.method.HandlerMethod;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;

@Slf4j
public class SystemInterceptor extends SaInterceptor {


    public SystemInterceptor(SaParamFunction<Object> auth) {
        this.auth = auth;
    }


    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        try {
            if (this.isAnnotation && handler instanceof HandlerMethod) {
                Method method = ((HandlerMethod)handler).getMethod();
                SaAnnotationStrategy.instance.checkMethodAnnotation.accept(method);
            }
            this.auth.run(handler);
        } catch (NotLoginException error) {
            //Sa-Token 已经帮助我们完成了拦截校验，其中包括 Token是否过期，用户是否登录等校验
            //所以这里只需要根据枚举码来返回信息即可，具体内容可参考cn.dev33.satoken.error.SaErrorCode
            log.error("Sa-Token 拦截器 Error -> {}", error.getMessage());
            //构建响应信息
            String responseJSON = buildResponse(error);
            //设置响应内容
            if (response.getContentType() == null) {
                response.setContentType("application/json; charset=utf-8");
            }
            response.getWriter().print(responseJSON);
            return false;
        }
        return true;
    }

    /**
     * @description: 构建响应信息
     * @author tangzhaofeng
     * @version 1.0
     */
    private static String buildResponse(NotLoginException error) {
        ApiResponse apiResponse = null;
        //根据错误码进行错误构建
        switch (error.getCode()) {
            case SaErrorCode.CODE_11012:
                apiResponse = ApiResponse.fail(APIResponseEnum.TOKEN_INVALID);
                break;
            case SaErrorCode.CODE_11011:
                apiResponse = ApiResponse.fail(APIResponseEnum.NOLOGIN);
                break;
            case SaErrorCode.CODE_11013:
                apiResponse = ApiResponse.fail(APIResponseEnum.TOKEN_EXPIRED);
                break;
            default:
                // 可以在这里处理其他情况，或者保持为空
                break;
        }
        return JSONUtil.toJsonStr(apiResponse);
    }
}
